using MediatR;
using Microsoft.Extensions.Logging;
using S.O.Api.Read.Application.Command.Medical;
using S.O.Domain.Dto.Output;
using S.O.Domain.Medical;
using S.O.ErrorCode;
using S.O.Interstructrue.Base;

namespace S.O.Api.Read.Application.Handler.Medical
{
    /// <summary>
    /// 获取处方列表处理器
    /// 负责查询和返回处方列表数据，支持分页和多条件筛选
    /// </summary>
    public class GetPrescriptionListHandler : IRequestHandler<GetPrescriptionListCommand, APIPaging<PrescriptionDto>>
    {
        /// <summary>
        /// 处方信息仓储
        /// </summary>
        private readonly IBaseRepository<PrescriptionModel> _prescriptionRepository;

        /// <summary>
        /// 处方药品明细仓储
        /// </summary>
        private readonly IBaseRepository<PrescriptionMedicineModel> _prescriptionMedicineRepository;

        /// <summary>
        /// 日志记录器
        /// </summary>
        private readonly ILogger<GetPrescriptionListHandler> _logger;

        /// <summary>
        /// 构造函数，通过依赖注入初始化所需服务
        /// </summary>
        /// <param name="prescriptionRepository">处方信息仓储</param>
        /// <param name="prescriptionMedicineRepository">处方药品明细仓储</param>
        /// <param name="logger">日志记录器</param>
        public GetPrescriptionListHandler(
            IBaseRepository<PrescriptionModel> prescriptionRepository,
            IBaseRepository<PrescriptionMedicineModel> prescriptionMedicineRepository,
            ILogger<GetPrescriptionListHandler> logger)
        {
            _prescriptionRepository = prescriptionRepository;
            _prescriptionMedicineRepository = prescriptionMedicineRepository;
            _logger = logger;
        }

        /// <summary>
        /// 处理获取处方列表命令
        /// </summary>
        /// <param name="request">查询命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>分页的处方列表</returns>
        public async Task<APIPaging<PrescriptionDto>> Handle(GetPrescriptionListCommand request, CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation("开始查询处方列表，页码: {PageIndex}, 页大小: {PageSize}", request.PageIndex, request.PageSize);

                // 构建查询条件
                var query = _prescriptionRepository.GetALL()
                    .Where(p => !p.IsDeleted && p.IsEnable);

                // 按患者ID筛选
                if (request.PatientId.HasValue)
                {
                    query = query.Where(p => p.PatientId == request.PatientId.Value);
                }

                // 按患者姓名模糊查询
                if (!string.IsNullOrWhiteSpace(request.PatientName))
                {
                    query = query.Where(p => p.PatientName.Contains(request.PatientName));
                }

                // 按医生姓名模糊查询
                if (!string.IsNullOrWhiteSpace(request.Doctor))
                {
                    query = query.Where(p => p.Doctor.Contains(request.Doctor));
                }

                // 按处方类型筛选
                if (!string.IsNullOrWhiteSpace(request.PrescriptionType))
                {
                    query = query.Where(p => p.PrescriptionType == request.PrescriptionType);
                }

                // 按处方状态筛选
                if (!string.IsNullOrWhiteSpace(request.Status))
                {
                    query = query.Where(p => p.Status == request.Status);
                }

                // 按日期范围筛选
                if (request.StartDate.HasValue)
                {
                    query = query.Where(p => p.CreateTime >= request.StartDate.Value);
                }
                if (request.EndDate.HasValue)
                {
                    var endDate = request.EndDate.Value.Date.AddDays(1); // 包含结束日期当天
                    query = query.Where(p => p.CreateTime < endDate);
                }

                // 按创建时间倒序排列
                query = query.OrderByDescending(p => p.CreateTime);

                // 计算总数
                var totalCount = query.Count();

                // 分页查询
                var prescriptions = query
                    .Skip((request.PageIndex - 1) * request.PageSize)
                    .Take(request.PageSize)
                    .ToList();

                // 获取处方ID列表
                var prescriptionIds = prescriptions.Select(p => p.Id).ToList();

                // 批量查询药品明细
                var medicines = _prescriptionMedicineRepository.GetALL()
                    .Where(m => prescriptionIds.Contains(m.PrescriptionId) && !m.IsDeleted && m.IsEnable)
                    .ToList();

                // 转换为DTO
                var prescriptionDtos = prescriptions.Select(p => new PrescriptionDto
                {
                    Id = p.Id,
                    PatientId = p.PatientId,
                    PatientName = p.PatientName,
                    PrescriptionType = p.PrescriptionType,
                    Diagnosis = p.Diagnosis,
                    Remark = p.Remark,
                    Doctor = p.Doctor,
                    Status = p.Status,
                    CreateTime = p.CreateTime,
                    Medicines = medicines
                        .Where(m => m.PrescriptionId == p.Id)
                        .OrderBy(m => m.SortOrder)
                        .Select(m => new PrescriptionMedicineDto
                        {
                            Id = m.Id,
                            PrescriptionId = m.PrescriptionId,
                            MedicineName = m.MedicineName,
                            Specification = m.Specification,
                            Dosage = m.Dosage,
                            Frequency = m.Frequency,
                            Duration = m.Duration,
                            Usage = m.Usage,
                            Remark = m.Remark,
                            SortOrder = m.SortOrder
                        }).ToList()
                }).ToList();

                _logger.LogInformation("处方列表查询完成，共查询到 {Count} 条记录", prescriptionDtos.Count);

                return new APIPaging<PrescriptionDto>
                {
                    PageDatas = prescriptionDtos,
                    TotalCount = totalCount
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "查询处方列表时发生错误");
                return new APIPaging<PrescriptionDto>
                {
                    PageDatas = new List<PrescriptionDto>(),
                    TotalCount = 0
                };
            }
        }
    }
}